package Engine.AIUGame
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	
	/**
	 * 显示层
	 */
	public class AIView extends AIBasic
	{
		static public const STYLE_LOCKON:uint = 0;
		static public const STYLE_PLATFORMER:uint = 1;
		static public const STYLE_TOPDOWN:uint = 2;
		static public const STYLE_TOPDOWN_TIGHT:uint = 3;
		static public const SHAKE_BOTH_AXES:uint = 0;
		static public const SHAKE_HORIZONTAL_ONLY:uint = 1;
		static public const SHAKE_VERTICAL_ONLY:uint = 2;
		
		
		static public var defaultZoom:Number = 1;
		
		
		public var deadzone:Rectangle;
		
		
		//显示层边缘
		public var bounds:Rectangle;
		
		//显示层跟随对象.
		public var target:AIObject;
		
		public var scroll:AIPoint;
		
		protected var _point:AIPoint;
		
		
		
		public var x:Number;
		public var y:Number;
		public var width:uint;
		public var height:uint;
		
		/**
		 * 显示层位图.
		 */
		public var buffer:BitmapData;
		public var screen:AISprite;
		
		
		internal var _flashSprite:Sprite;
		internal var _flashOffsetX:Number;
		internal var _flashOffsetY:Number;
		
		private var _zoom:Number;
		private var _flashBitmap:Bitmap;
		
		private var _flashRect:Rectangle;
		private var _flashPoint:Point;
		
		private var _fxFlashColor:uint;
		private var _fxFlashDuration:Number;
		private var _fxFlashAlpha:Number;
		
		private var _fill:BitmapData;
		
		/**
		 * 创建一个AIView层
		 */
		public function AIView(X:int,Y:int,Width:int,Height:int,Zoom:Number=0)
		{
			x = X;
			y = Y;
			width = Width;
			height = Height;
			
			target = null;
			
			scroll = new AIPoint();
			
			screen = new AISprite();
			screen.makeGraphic(width,height,0);
			screen.setOrigin(0,0);
			buffer = screen.pixels;
			
			_flashBitmap = new Bitmap(buffer);
			_flashBitmap.x = -width*0.5;
			_flashBitmap.y = -height*0.5;
			
			
			_flashSprite = new Sprite();
			zoom = Zoom;
			_flashOffsetX = width*0.5*zoom;
			_flashOffsetY = height*0.5*zoom;
			_flashSprite.x = x + _flashOffsetX;
			_flashSprite.y = y + _flashOffsetY;
			_flashSprite.addChild(_flashBitmap);
			_flashRect = new Rectangle(0,0,width,height);
			_flashPoint = new Point();
			
			_fxFlashColor = 0;
			_fxFlashDuration = 0.0;
			_fxFlashAlpha = 0.0;
			
			_fill = new BitmapData(width,height,true,0);
		}
		
		/**
		 * Clean up memory.
		 */
		override public function destroy():void
		{
			screen.destroy();
			screen = null;
			target = null;
			buffer = null;
			_flashBitmap = null;
			_flashRect = null;
			_flashPoint = null;
			_fill = null;
		}
		
		/**
		 * Updates the camera scroll as well as special effects like screen-shake or fades.
		 */
		override public function update():void
		{
			if(target != null)
			{
				if(deadzone == null)
					focusOn(target.getMidpoint(_point));
				else
				{
					var edge:Number;
					var targetX:Number = target.x + ((target.x > 0)?0.0000001:-0.0000001);
					var targetY:Number = target.y + ((target.y > 0)?0.0000001:-0.0000001);
					
					edge = targetX - deadzone.x;
					if(scroll.x > edge)
						scroll.x = edge;
					edge = targetX + target.width - deadzone.x - deadzone.width;
					if(scroll.x < edge)
						scroll.x = edge;
					
					edge = targetY - deadzone.y;
					if(scroll.y > edge)
						scroll.y = edge;
					edge = targetY + target.height - deadzone.y - deadzone.height;
					if(scroll.y < edge)
						scroll.y = edge;
				}
			}
			
			if(bounds != null)
			{
				if(scroll.x < bounds.left)
					scroll.x = bounds.left;
				if(scroll.x > bounds.right - width)
					scroll.x = bounds.right - width;
				if(scroll.y < bounds.top)
					scroll.y = bounds.top;
				if(scroll.y > bounds.bottom - height)
					scroll.y = bounds.bottom - height;
			}
			
			
		}
		
		
		public function setBounds(X:Number=0, Y:Number=0, Width:Number=0, Height:Number=0, UpdateWorld:Boolean=false):void
		{
			if(bounds == null)
				bounds = new Rectangle(X,Y,Width,Height);
			else
			{
				bounds.x = X;
				bounds.y = Y;
				bounds.width = Width;
				bounds.height = Height;
			}
			//if(UpdateWorld)
			//	FlxG.worldBounds.copyFrom(bounds);
			update();
		}
		
		
		public function follow(Target:AIObject, Style:uint=STYLE_LOCKON):void
		{
			target = Target;
			var helper:Number;
			switch(Style)
			{
				case STYLE_PLATFORMER:
					var w:Number = width/8;
					var h:Number = height/3;
					deadzone = new Rectangle((width-w)/2,(height-h)/2 - h*0.25,w,h);
					break;
				case STYLE_TOPDOWN:
					helper = AIGDate.max(width,height)/4;
					deadzone = new Rectangle((width-helper)/2,(height-helper)/2,helper,helper);
					break;
				case STYLE_TOPDOWN_TIGHT:
					helper = AIGDate.max(width,height)/8;
					deadzone = new Rectangle((width-helper)/2,(height-helper)/2,helper,helper);
					break;
				case STYLE_LOCKON:
				default:
					deadzone = null;
					break;
			}
		}
		
		public function focusOn(Point:AIPoint):void
		{
			Point.x += (Point.x > 0)?0.0000001:-0.0000001;
			Point.y += (Point.y > 0)?0.0000001:-0.0000001;
			scroll.make(Point.x - width*0.5,Point.y - height*0.5);
		}
		
		
		public function fill(Color:uint,BlendAlpha:Boolean = false):void
		{
			_fill.fillRect(_flashRect,Color);
			buffer.copyPixels(_fill,_flashRect,_flashPoint,null,null,BlendAlpha);
		}
		
		
		/**
		 * The zoom level of this camera. 1 = 1:1, 2 = 2x zoom, etc.
		 */
		public function get zoom():Number
		{
			return _zoom;
		}
		
		/**
		 * @private
		 */
		public function set zoom(Zoom:Number):void
		{
			if(Zoom == 0)
				_zoom = defaultZoom;
			else
				_zoom = Zoom;
			setScale(_zoom,_zoom);
		}
		
		public function setScale(X:Number,Y:Number):void
		{
			_flashSprite.scaleX = X;
			_flashSprite.scaleY = Y;
		}
		
		
		public function getContainerSprite():Sprite
		{
			return _flashSprite;
		}

	}
}